package com.sky.service.admin.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.mapper.user.OrderMapper;
import com.sky.mapper.user.UserMapper;
import com.sky.pojo.Orders;
import com.sky.service.admin.ReportService;
import com.sky.service.admin.WorkSpaceService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Select;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j

public class ReportServiceImpl  implements ReportService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WorkSpaceService workSpaceService;

    /**
     * 销售数据统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {
        //存放从begin到end日期之间的每天的日期
        List<LocalDate> dateList=new ArrayList<>();

        dateList.add(begin);
        while (!begin.equals(end)){
            //计算日期的后一天
            //例如开始2.20,结束2.25,就让2.20一直加,begin=25了就结束循环
            begin=begin.plusDays(1);
            dateList.add(begin);
        }
        TurnoverReportVO turnoverReportVO=new TurnoverReportVO();
        turnoverReportVO.setDateList(StringUtils.join(dateList,","));


        //遍历日期集合,得到每一天的日期,再根据这个每一天的日期去查询营业额
        List<Double> amounts=new ArrayList<>();
        for (LocalDate date : dateList) {
            LocalDateTime beginTimeOfDay = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTimeOfDay = LocalDateTime.of(date, LocalTime.MAX);
            Map map=new HashMap();
            map.put("begin",beginTimeOfDay);
            map.put("end",endTimeOfDay);
            map.put("status", Orders.COMPLETE_ORDER);
            Double turnover=orderMapper.getBySum(map);
            if (turnover==null){
                turnover=0.0;
            }else{
                turnover=turnover;
            }
            amounts.add(turnover);
        }
        turnoverReportVO.setTurnoverList(StringUtils.join(amounts,","));

        return turnoverReportVO;


    }


    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO getTuserStatistics(LocalDate begin, LocalDate end) {
        //先统计日期集合
        List<LocalDate> dateList=new ArrayList<>();
        UserReportVO userReportVO=new UserReportVO();
        //放入开始日期
        dateList.add(begin);
        while (!begin.equals(end)){
            begin=begin.plusDays(1);
            dateList.add(begin);
        }
        userReportVO.setDateList(StringUtils.join(dateList,","));


        List<Integer> userTotal=new ArrayList<>();
        List<Integer> newUserTotal=new ArrayList<>();
        //统计用户(日期小于等于今天的,比如2.20,就要统计2.13-2.20之间所有的数量和)
        for (LocalDate date : dateList) {
            LocalDateTime beginDateTime = LocalDateTime.of(date,LocalTime.MIN);
            LocalDateTime endDateTime = LocalDateTime.of(date,LocalTime.MAX);
            Map map=new HashMap();

            map.put("end",endDateTime);
            Integer total=userMapper.getTotolByUser(map);

            map.put("begin",beginDateTime);
            Integer newTotal=userMapper.getTotolByUser(map);
            if (total==null){
                total=0;
            }else{
                total=total;
            }

            if (newTotal==null){
                total=0;
            }else{
                newTotal=newTotal;
            }
            userTotal.add(total);
            newUserTotal.add(newTotal);
        }
            userReportVO.setTotalUserList(StringUtils.join(userTotal,","));
            userReportVO.setNewUserList(StringUtils.join(newUserTotal,","));



        //统计新用户(当日新增的)

        return userReportVO;
    }


    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public OrderReportVO getOrdersStatistics(LocalDate begin, LocalDate end) {
        //日期
        List<LocalDate> dateList=new ArrayList<>();

        OrderReportVO orderReportVO=new OrderReportVO();

        //存放每天订单总数
        List<Integer> orderCountList=new ArrayList<>();
        //存放每天有效订单总数
        List<Integer> validOrderCountList=new ArrayList<>();
        dateList.add(begin);
        if (!begin.equals(end)){
            begin.plusDays(1);
            dateList.add(begin);
        }
        for (LocalDate date : dateList) {
            LocalDateTime beginDateTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endDateTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map=new HashMap();
            map.put("begin",beginDateTime);
            map.put("end",endDateTime);
            //每日总订单数 大于等于
            Integer orderCount=orderMapper.getByOrder(map);
            orderCountList.add(orderCount);

            //每日有效订单数
            map.put("status",Orders.COMPLETE_ORDER);
            Integer validOrderCount=orderMapper.getByOrder(map);
            validOrderCountList.add(validOrderCount);



        }

        //总订单数
        Integer totalOrderCount = orderCountList.stream().reduce(Integer::sum).get();
        //总有效订单数
        Integer totalvalidOrderCount = validOrderCountList.stream().reduce(Integer::sum).get();
        //订单完成率(每日有效订单数/每日总订单数)
        Double orderCompletionRate=0.0;
        if (orderCompletionRate!=0){
            orderCompletionRate= totalvalidOrderCount.doubleValue()/totalOrderCount;
        }


        orderReportVO.setDateList(StringUtils.join(dateList,","));
        orderReportVO.setOrderCountList(StringUtils.join(orderCountList,","));
        orderReportVO.setValidOrderCountList(StringUtils.join(validOrderCountList,","));
        orderReportVO.setTotalOrderCount(totalOrderCount);
        orderReportVO.setValidOrderCount(totalvalidOrderCount);
        orderReportVO.setOrderCompletionRate(orderCompletionRate);


        return orderReportVO;
    }

    @Override
    public SalesTop10ReportVO ordersTop10(LocalDate begin, LocalDate end) {
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(begin, LocalTime.MAX);
        GoodsSalesDTO goodsSalesDTO=new GoodsSalesDTO();
        SalesTop10ReportVO salesTop10ReportVO=new SalesTop10ReportVO();
        List<GoodsSalesDTO> sales = orderMapper.getSales(beginTime, endTime);

        List<String> names = sales.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        List<Integer> numbers = sales.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
        salesTop10ReportVO.setNameList(StringUtils.join(names,","));
        salesTop10ReportVO.setNumberList(StringUtils.join(numbers,","));

        return salesTop10ReportVO;
    }

    @Override
    public void exportBusinessData(HttpServletResponse response)  {
        //查询数据库,最近30天
        LocalDate startDate = LocalDate.now().minusDays(30);
        LocalDate endDate = LocalDate.now().minusDays(1);
        //处理日期格式

        BusinessDataVO businessDataVO = workSpaceService.businessData(LocalDateTime.of(startDate, LocalTime.MIN), LocalDateTime.of(endDate, LocalTime.MAX));

        //通过poi将数据写入到excel
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");

        try {
            XSSFWorkbook excel = new XSSFWorkbook(in);
            XSSFSheet sheet1 = excel.getSheet("Sheet1");
            XSSFRow row1 = sheet1.getRow(1);//行
            XSSFCell cell = row1.getCell(1);//第二行的第几个单元格
            cell.setCellValue("时间:"+startDate+"-"+endDate);//给第二个单元格填充时间

            XSSFRow row3 = sheet1.getRow(3);//第四行
            XSSFCell cell43 = row3.getCell(2);//第四行第三格
            XSSFCell cell45 = row3.getCell(4);//第四行第五格
            XSSFCell cell47 = row3.getCell(6);//第四行第七格
            cell43.setCellValue(businessDataVO.getTurnover());//营业额
            cell45.setCellValue(businessDataVO.getOrderCompletionRate());//订单完成率
            cell47.setCellValue(businessDataVO.getNewUsers());//新增用户

            XSSFRow row4 = sheet1.getRow(4);//第五行
            XSSFCell cell53 = row4.getCell(2);//第五行第三格
            XSSFCell cell55 = row4.getCell(4);//第五行第五格
            cell53.setCellValue(businessDataVO.getValidOrderCount());
            cell55.setCellValue(businessDataVO.getUnitPrice());


            //填充明细数据
            for (int i = 0; i < 30; i++) {
                LocalDate date= startDate.plusDays(i);
                BusinessDataVO dataVo = workSpaceService.businessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
                XSSFRow dataRow = sheet1.getRow(7 + i);//行
                XSSFCell dataRowCell2 = dataRow.getCell(1);//第二格
                XSSFCell dataRowCell3 = dataRow.getCell(2);//第三格
                XSSFCell dataRowCell4 =  dataRow.getCell(3);//第四格
                XSSFCell dataRowCell5 =  dataRow.getCell(4);//第五格
                XSSFCell dataRowCell6 =   dataRow.getCell(5);//第六格
                XSSFCell dataRowCell7 =   dataRow.getCell(6);//第七格

                //日期
                dataRowCell2.setCellValue(date.toString());
                //营业额
                Double turnover= dataVo.getTurnover();
                if (turnover==null){
                    turnover=0.0;
                }
                dataRowCell3.setCellValue(turnover);
                //有效订单
                dataRowCell4.setCellValue(dataVo.getValidOrderCount());
                //订单完成率
                dataRowCell5.setCellValue(dataVo.getOrderCompletionRate());
                //平均客单价
                dataRowCell6.setCellValue(dataVo.getUnitPrice());
                //新增用户数
                dataRowCell7.setCellValue(dataVo.getNewUsers());

            }


            //下载excel到客户端
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);




            //关闭资源
            outputStream.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }
}
